home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / misc / avmnfaxsrc1_33.lha / ecasc2fax.c < prev    next >
C/C++ Source or Header  |  1994-05-26  |  10KB  |  464 lines

  1. /*
  2.  * asc2fax.c
  3.  *
  4.  * Copyright (C) 1993 by Olaf 'Rhialto' Seibert. All rights reserved.
  5.  *
  6.  * V24.05.93: Initial release
  7.  * V29.05.93: Fixed unsigned character bug
  8.  *
  9.  * $Id: asc2fax.c,v 1.2 1993/06/11 16:33:37 Rhialto Exp $
  10.  * $Log: asc2fax.c,v $
  11.  * Revision 1.2  1993/06/11  16:33:37  Rhialto
  12.  * First real RCS checkin
  13.  *
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20.  
  21. #define INTUI_V36_NAMES_ONLY
  22. #include <utility/tagitem.h>
  23. #include <intuition/intuition.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/alib_protos.h>
  26. #include <clib/graphics_protos.h>
  27. #include <clib/intuition_protos.h>
  28. #include <clib/diskfont_protos.h>
  29.  
  30. #include "faxfile.h"
  31.  
  32. int FaxFine = 1;
  33.  
  34. #define RASTERWIDTH LINE_BITS
  35. #define ESC        "\33"
  36. #define CSI        "\233"
  37. #define uchar(x)    ((unsigned char)(x))
  38.  
  39. int        verbose;
  40. int        xoffset = /*5*/0;
  41. int        yoffset = /*5*/0;
  42. int        invert;
  43. void           *IntuitionBase;
  44. void           *GfxBase;
  45. void           *DiskFontBase;
  46. struct BitMap    BitMap;
  47. struct RastPort EmergencyRastPort;
  48. struct RastPort *RastPort;
  49. struct Window  *Window = 0;
  50. struct TextFont *Font;
  51. struct TextFont *OldFont;
  52. struct NewWindow NewWindow = {
  53.     0, 20,            /* LeftEdge, TopEdge */
  54.     640, 0,            /* Width, Height (calculated and set) */
  55.     1, 1,            /* DetailPen, BlockPen */
  56.     0,                /* IDCMPFlags */
  57.     WFLG_SUPER_BITMAP | WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH |
  58.     WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEGADGET | WFLG_SIZEBRIGHT, /* Flags */
  59.     NULL,            /* FirstGadget */
  60.     NULL,            /* CheckMark */
  61.     NULL,            /* Title */
  62.     NULL,            /* Screen */
  63.     &BitMap,            /* BitMap */
  64.     20,20, -1,0,        /* Min/Max Width/Height */
  65.     WBENCHSCREEN        /* Type */
  66. };
  67. struct TagItem TextTags[] = {
  68.     TA_DeviceDPI, X_DPI | Y_DPI << 16,
  69.     TAG_END
  70. };
  71. struct TTextAttr TextAttr = {
  72.     "courier.font", 30, FSF_TAGGED, 0, TextTags
  73. };
  74.  
  75. void
  76. meminvert(unsigned char *d, int size)
  77. {
  78.     if (((long) d & 0x01) == 0) {
  79.     while (size >= 4) {
  80.         *(long *)d ^= 0xFFFFFFFF;
  81.         d += 4;
  82.         size -= 4;
  83.     }
  84.     }
  85.     while (size > 0) {
  86.     *d++ ^= 0xFF;
  87.     size--;
  88.     }
  89. }
  90.  
  91. struct TextInfo {
  92.     struct RastPort *rp;
  93.     int         xoffset;
  94. } ti;
  95.  
  96. unsigned char  *
  97. DoText(unsigned char *text, int len)
  98. {
  99.     if (len > 0)
  100.     Text(ti.rp, text, len);
  101.     return text + len;
  102. }
  103.  
  104. unsigned char  *
  105. DoCSI(unsigned char *text)
  106. {
  107.     int         arg[8];
  108.     int         narg = 0;
  109.     int         i;
  110.  
  111.     memset(arg, 0, sizeof(arg));
  112.     /* CSI 0 x and CSI x are indistinguishable */
  113.     for(;;text++) {
  114.     while (isdigit(text[0])) {
  115.         if (narg < 8) {
  116.         arg[narg] *= 10;
  117.         arg[narg] += text[0] - '0';
  118.         }
  119.         text++;
  120.     }
  121.     narg++;
  122.     if (text[0] != ';')
  123.         break;
  124.     }
  125.     if (narg > 8)
  126.     narg = 8;
  127.  
  128.     switch (*text++) {
  129.     case 'm':   /* Select graphic rendition */
  130.     for (i = 0; i < narg; i++) {
  131.         switch (arg[i]) {
  132.         case 0:    /* plain */
  133.         SetSoftStyle(ti.rp, FS_NORMAL, FSF_BOLD|FSF_ITALIC|FSF_UNDERLINED);
  134.         SetDrMd(ti.rp, JAM1);
  135.         break;
  136.         case 1:    /* bold */
  137.         SetSoftStyle(ti.rp, FSF_BOLD, FSF_BOLD);
  138.         break;
  139.         case 3:    /* italic */
  140.         SetSoftStyle(ti.rp, FSF_ITALIC, FSF_ITALIC);
  141.         break;
  142.         case 4:    /* underline */
  143.         SetSoftStyle(ti.rp, FSF_UNDERLINED, FSF_UNDERLINED);
  144.         break;
  145.         case 7:    /* inverse video */
  146.         SetDrMd(ti.rp, JAM1 | INVERSVID);
  147.         break;
  148.         case 22:     /* not bold */
  149.         SetSoftStyle(ti.rp, 0, FSF_BOLD);
  150.         break;
  151.         case 23:     /* not italic */
  152.         SetSoftStyle(ti.rp, 0, FSF_ITALIC);
  153.         break;
  154.         case 24:     /* not underline */
  155.         SetSoftStyle(ti.rp, 0, FSF_UNDERLINED);
  156.         break;
  157.         case 27:     /* not inverse video */
  158.         SetDrMd(ti.rp, JAM1);
  159.         break;
  160.         }
  161.     }
  162.     break;
  163.     case 'x':           /* set left offset */
  164.     ti.xoffset = arg[0];
  165.     break;
  166.     }
  167.  
  168.     return text;
  169. }
  170.  
  171. unsigned char  *
  172. DoCtrl(unsigned char *text)
  173. {
  174.     switch (*text++) {
  175.     case '\t':          /* tab */
  176.     {
  177.         int         charpos;
  178.  
  179.         charpos = (ti.rp->cp_x - ti.xoffset) / ti.rp->TxWidth;
  180.         charpos = (charpos + 8) & ~7;
  181.         Move(ti.rp, ti.xoffset + charpos * ti.rp->TxWidth, ti.rp->cp_y);
  182.     }
  183.     break;
  184.     case '\n':          /* newline */
  185.     Move(ti.rp, ti.xoffset, ti.rp->cp_y + ti.rp->TxHeight);
  186.     break;
  187.     case '\f':          /* formfeed */
  188.     SetRast(ti.rp, 0);
  189.     Move(ti.rp, ti.xoffset, ti.rp->TxBaseline);
  190.     break;
  191.     case uchar('\233'): /* control sequence introducer */
  192.     goto csi;
  193.     case '\033':        /* escape */
  194.     switch (*text++) {
  195.     case 'c':       /* reset */
  196.         ti.xoffset = 0;
  197.         ti.rp->Mask = 0x0001;
  198.         SetAPen(ti.rp, 1);
  199.         SetBPen(ti.rp, 0);
  200.         DoCtrl("\f");
  201.         DoCSI("0m");
  202.         break;
  203.     case '[':       /* CSI */
  204.     csi:
  205.         text = DoCSI(text);
  206.         break;
  207.     }
  208.     break;
  209.     }
  210.  
  211.     return text;
  212. }
  213.  
  214. void
  215. WinWrite(unsigned char *text)
  216. {
  217.     while (*text) {
  218.     unsigned char  *p;
  219.     int        len;
  220.  
  221.     /* First, determine how much real text we have */
  222.     for (len = 0, p = text; isprint(*p); p++) {
  223.         len++;
  224.     }
  225.     text = DoText(text, len);
  226.     if (*text && !isprint(*text))
  227.         text = DoCtrl(text);
  228.     }
  229. }
  230.  
  231. void
  232. WinWriteInit(void)
  233. {
  234.     ti.rp = RastPort;
  235.     DoCtrl(ESC"c");
  236. }
  237.  
  238.  
  239. long
  240. dofile(char *ascname, void *faxp)
  241. {
  242.     unsigned char   line[256];
  243.     FILE       *file;
  244.     struct RastPort *rp = RastPort;
  245.  
  246.     file = fopen(ascname, "r");
  247.     if (file == NULL) {
  248.     printf("Can't open file %s.\n", ascname);
  249.     return 1;
  250.     }
  251.  
  252.     faxout_begin_page(faxp, FaxFine, 0);
  253.  
  254.     WinWriteInit();
  255.     /* reset, set x offset */
  256.     sprintf(line, ESC"c" CSI"%dx", xoffset);
  257.     WinWrite(line);
  258.  
  259.     if (yoffset) {
  260.     int        i;
  261.  
  262.     for (i = 0; i < yoffset; i++)
  263.         tofax(faxp, BitMap.Planes[0], RASTERWIDTH);
  264.     }
  265.  
  266.     for (;;) {
  267.     int        i;
  268.     unsigned char  *plane;
  269.  
  270.     if (feof(file))
  271.         break;
  272.     if (fgets(line, sizeof(line), file) == NULL)
  273.         break;
  274.     if (plane = strchr(line, '\n'))
  275.         *plane = '\0';
  276.  
  277.     if (verbose)
  278.         printf("%s\n", line);
  279.     WinWrite("\f");
  280.     WinWrite(line);
  281.  
  282.     if (Window)
  283.       SyncSBitMap(rp->Layer);
  284.     plane = BitMap.Planes[0];
  285.     for (i = 0; i < Font->tf_YSize; i++) {
  286.         if (invert)
  287.         meminvert(plane, BitMap.BytesPerRow);
  288.         tofax(faxp, plane, RASTERWIDTH);
  289.         plane += BitMap.BytesPerRow;
  290.         if (!FaxFine) {
  291.           plane += BitMap.BytesPerRow; /* decimate -- skip the next row */
  292.           i++;
  293.         }
  294.     }
  295.     }
  296.  
  297.     faxout_end_page(faxp);
  298.     fclose(file);
  299.  
  300.     return 0;
  301. }
  302.  
  303. void
  304. openall(void)
  305. {
  306.     /* Libraries */
  307.     IntuitionBase = OpenLibrary("intuition.library", 33);
  308.     if (IntuitionBase == NULL) {
  309.     printf("Needs intuition V33+.\n");
  310.     exit(10);
  311.     }
  312.     GfxBase = OpenLibrary("graphics.library", 33);
  313.     if (GfxBase == NULL) {
  314.     printf("Needs gfx V33+.\n");
  315.     exit(10);
  316.     }
  317.     DiskFontBase = OpenLibrary("diskfont.library", 34);
  318.     if (DiskFontBase == NULL) {
  319.     printf("Needs diskfont V34+.\n");
  320.     exit(10);
  321.     }
  322.     /* Font for window; sorry for the strange order */
  323.     printf("Opening DiskFont... (This may take a while)\n");
  324.     Font = OpenDiskFont((struct TextAttr *)&TextAttr);
  325.     if (Font == NULL) {
  326.     printf("No %s %d!\n", TextAttr.tta_Name, TextAttr.tta_YSize);
  327.     exit(10);
  328.     }
  329.     NewWindow.Height = Font->tf_YSize + 16;  /* slight safety fudge */
  330.     /* Raster for text */
  331.     InitBitMap(&BitMap, 1, RASTERWIDTH, NewWindow.Height);
  332.     if ((BitMap.Planes[0] = AllocRaster(RASTERWIDTH, NewWindow.Height)) == NULL) {
  333.     printf("No plane\n");
  334.     exit(10);
  335.     }
  336.  
  337. #if 0
  338.     /* Window for raster. For showing-off purposes only. */
  339.     if ((Window = OpenWindow(&NewWindow)) == NULL) {
  340.     printf("No window (probably too large). Will do without.\n");
  341.     }
  342. #else
  343.     Window = 0;
  344. #endif
  345.  
  346.     if (Window) {
  347.     RastPort = Window->RPort;
  348.     } else {
  349.     RastPort = &EmergencyRastPort;
  350.     InitRastPort(RastPort);
  351.     RastPort->BitMap = &BitMap;
  352.     }
  353.     RastPort->Mask = 0x0001;
  354.     OldFont = RastPort->Font;
  355.     SetFont(RastPort, Font);
  356. }
  357.  
  358.  
  359. /*
  360.  * Clean up system stuff in case of exit
  361.  */
  362. void
  363. cleanup(void)
  364. {
  365.     if (Font) {
  366.     SetFont(RastPort, OldFont);
  367.     CloseFont(Font);
  368.     }
  369.     if (Window) {
  370.     CloseWindow(Window);
  371.     }
  372.     if (GfxBase) {
  373.     if (BitMap.Planes[0]) {
  374.         FreeRaster(BitMap.Planes[0], RASTERWIDTH, NewWindow.Height);
  375.         BitMap.Planes[0] = NULL;
  376.     }
  377.     CloseLibrary(GfxBase);
  378.     }
  379.     if (IntuitionBase) {
  380.     CloseLibrary(IntuitionBase);
  381.     }
  382.     if (DiskFontBase) {
  383.     CloseLibrary(DiskFontBase);
  384.     }
  385. }
  386.  
  387. int
  388. main(int argc, char **argv)
  389. {
  390.     char       *outfile = "ascii.g3";
  391.     struct faxout  *faxp;
  392.     int         rawfax = 0;
  393.     int         append = 0;
  394.     extern char    *optarg;
  395.     extern int        optind;
  396.     extern int        getopt(int, char **, char *);
  397.     int         errflg = 0;
  398.     int         c;
  399.  
  400.     while ((c = getopt(argc, argv, "af:io:rs:vx:yl:")) != -1) {
  401.     switch (c) {
  402.     case 'a':
  403.         append = 1;
  404.         break;
  405.     case 'f':
  406.         TextAttr.tta_Name = optarg;
  407.         break;
  408.     case 's':
  409.         TextAttr.tta_YSize = atoi(optarg);
  410.         break;
  411.     case 'i':
  412.         invert = 1;
  413.         break;
  414.     case 'o':
  415.         outfile = optarg;
  416.         break;
  417.     case 'r':
  418.         // rawfax++;
  419.         break;
  420.     case 'v':
  421.         verbose = TRUE;
  422.         break;
  423.         case 'l':
  424.         FaxFine = 0;
  425.             break;
  426.     case 'x':
  427.         xoffset = atoi(optarg);
  428.         break;
  429.     case 'y':
  430.         yoffset = atoi(optarg);
  431.         break;
  432.     case '?':
  433.         errflg++;
  434.         break;
  435.     }
  436.     }
  437.  
  438.     if (errflg || optind >= argc) {
  439.     printf(
  440. "Usage: asc2fax [-o fax-file (ascii.g3)] [-r raw faxfile] [-a (append)]\n"
  441. "               [-x/y x/y-offset (50)] [-v] [-i (invert)]\n"
  442. "               [-f name.font] [-s fontsize] [-l (low density)] ascii-files\n");
  443.     exit(EXIT_FAILURE);
  444.     }
  445.  
  446.     atexit(cleanup);
  447.     openall();
  448.  
  449.     faxp = faxout_open_fp(fopen(outfile, append? "ab": "wb"), rawfax);
  450.     if (faxp == NULL) {
  451.     fprintf(stderr, "can't open output file %s.\n", outfile);
  452.     goto fail;
  453.     }
  454.  
  455.     while (optind < argc) {
  456.     dofile(argv[optind], faxp);
  457.     optind++;
  458.     }
  459.  
  460.     faxout_close(faxp);
  461. fail:
  462.     /* atexit function cleans up here */
  463. }
  464.